package com.lanyun.aicorrectassistant.handler;

import com.alibaba.dashscope.aigc.generation.GenerationParam;
import com.alibaba.dashscope.aigc.generation.GenerationResult;
import com.alibaba.dashscope.common.Message;
import com.alibaba.dashscope.common.Role;

import com.alibaba.dashscope.exception.NoApiKeyException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.model.OSSObject;
import com.google.common.base.Strings;
import com.lanyun.aicorrectassistant.basic.entity.AssignmentTemplates;
import com.lanyun.aicorrectassistant.basic.entity.StudentAssignments;
import com.lanyun.aicorrectassistant.basic.entity.UserApiKey;
import com.lanyun.aicorrectassistant.basic.service.AssignmentTemplatesService;
import com.lanyun.aicorrectassistant.basic.service.GradingResultsService;
import com.lanyun.aicorrectassistant.basic.service.UserApiKeyService;
import com.lanyun.aicorrectassistant.config.StorageConfig;
import com.lanyun.aicorrectassistant.context.LoginContextHolder;
import com.lanyun.aicorrectassistant.enums.IsDeletedFlagEnum;
import io.netty.util.internal.StringUtil;
import io.reactivex.Flowable;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.dashscope.aigc.generation.Generation;
import com.lanyun.aicorrectassistant.basic.service.StudentAssignmentsService;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import reactor.core.publisher.Flux;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.Collections;

@Service
@Slf4j
public class AssignmentGradingService {
    private static final Logger logger = LoggerFactory.getLogger(AssignmentGradingService.class);

    @Resource
    private StudentAssignmentsService studentAssignmentsService;

    @Resource
    private AssignmentTemplatesService assignmentTemplatesService;

    @Resource
    private UserApiKeyService userApiKeyService;

    @Resource
    private OSS ossClient;

    @Resource
    private StorageConfig storageConfig;


    // 深度思考模型配置
    @Bean
    public Generation aiGeneration() {
        return new Generation();
    }

    public Flux<String> saveGradingResult(Long id) {
        StudentAssignments assignment = studentAssignmentsService.queryById(id);
        if (assignment == null) {
            throw new IllegalArgumentException("作业记录不存在");
        }

        String apikey = null;

        UserApiKey queryEntity = new UserApiKey();
        queryEntity.setUserId(assignment.getStudentId().toString());
        queryEntity.setIsActive(1);
        queryEntity.setIsDeleted(IsDeletedFlagEnum.UN_DELETED.getVal());
        UserApiKey userApiKey = userApiKeyService.queryByCondition(queryEntity);
        if (userApiKey != null && userApiKey.getIsActive() == 1 && userApiKey.getApiKey() != null) {
//            throw new IllegalArgumentException("用户未配置API Key");
            apikey = userApiKey.getApiKey();
        } else {
            queryEntity.setUserId(LoginContextHolder.getLoginId());
            userApiKey = userApiKeyService.queryByCondition(queryEntity);
            apikey = userApiKey.getApiKey();
        }

        try {

            AssignmentTemplates assignmentTemplates = validateTemplate(assignment.getTemplateId());

            String fileContent = readAssignmentContent(assignment.getFilePath());
            String fullPrompt = buildFullPrompt(assignmentTemplates, fileContent);

            GenerationParam param = buildGenerationParam(fullPrompt, apikey);
            Generation gen = new Generation();

            Flowable<GenerationResult> resultFlowable = gen.streamCall(param);
            return Flux.from(resultFlowable)
                    .map(this::processGenerationResult)
                    .doOnError(e -> handleError(e))
                    .doFinally(signalType -> cleanup());

        } catch (Exception e) {
            return Flux.error(e);
        }
    }

    private GenerationParam buildGenerationParam(String prompt, String apikey) throws NoApiKeyException {
        if (Strings.isNullOrEmpty(apikey)) {
            throw new IllegalArgumentException("用户未配置API Key");
        }

        Message userMsg = Message.builder()
                .role(Role.USER.getValue())
                .content(prompt)
                .build();

        return GenerationParam.builder()
                .apiKey(apikey)
                .model("deepseek-r1")
                .messages(Collections.singletonList(userMsg))
                .resultFormat(GenerationParam.ResultFormat.MESSAGE)
                .incrementalOutput(true)
                .maxTokens(10000)
                .temperature(0.7f)
                .topP(0.9)
                .topK(0)
                .enableSearch(true)
                .seed(0)
                .build();
    }

    private String processGenerationResult(GenerationResult result) {
        StringBuilder response = new StringBuilder();
        String reasoning = result.getOutput().getChoices().get(0).getMessage().getReasoningContent();
        String content = result.getOutput().getChoices().get(0).getMessage().getContent();

        if (!reasoning.isEmpty()) {
            response.append("[思考] ").append(reasoning);
        }
        if (!content.isEmpty()) {
            response.append("[批改] ").append(content);
        }
        return response.toString();
    }

    private void handleError(Throwable e) {
        // 添加错误处理逻辑，如日志记录
    }

    private void cleanup() {
        // 添加清理资源逻辑
    }


    private String buildFullPrompt(AssignmentTemplates template, String content) {
        return String.format(
                "## 核心任务要求%n" +
                        "深度理解教师批改要求：%n" +
                        "```%n" +
                        "%s%n" +
                        "```%n" +
                        "## 学生作业内容%n" +
                        "```%n" +
                        "%s%n" +
                        "```",
                template.getAiPromptTemplate().trim(),
                content
        );
    }


    private String readAssignmentContent(String filePath) throws Exception {
        String objectName = extractObjectName(filePath);

        try (OSSObject ossObject = ossClient.getObject(
                storageConfig.getAliyunOss().getBucketName(),
                objectName);
             InputStream contentStream = ossObject.getObjectContent();
             XWPFDocument document = new XWPFDocument(contentStream);
             XWPFWordExtractor extractor = new XWPFWordExtractor(document)) {

            return extractor.getText();
        } catch (IOException e) {
            throw new RuntimeException("作业文件读取失败", e);
        }

    }

    private String extractObjectName(String url) throws UnsupportedEncodingException, URISyntaxException {
        String decodedUrl = URLDecoder.decode(url, StandardCharsets.UTF_8);
        URI uri = new URI(decodedUrl);
        String path = uri.getPath();
        return path.startsWith("/") ? path.substring(1) : path;
    }

    private AssignmentTemplates validateTemplate(Long templateId) {
        AssignmentTemplates template = assignmentTemplatesService.queryById(templateId);
        if (template == null) {
            throw new RuntimeException("无效的作业模板");
        }
        return template;
    }


}